package com.ydy.reptile.service.impl;

import com.ydy.common.model.Drug;
import com.ydy.common.model.DrugDetail;
import com.ydy.common.util.CodeUtil;
import com.ydy.common.util.HttpsUtil;
import com.ydy.reptile.mapper.DrugMapper;
import com.ydy.reptile.service.DrugService;
import org.apache.commons.collections4.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

@Service
public class DrugServiceImpl implements DrugService {

    private static Logger LOGGER = LoggerFactory.getLogger(DrugServiceImpl.class);

    @Autowired
    private DrugMapper drugMapper;

    Integer tempPage = 0;

    @Override
    public void reptileDrugInfo(String baseUri,Integer nowPage) {
        try {
            List<Drug> drugList = new ArrayList<>();

            List<TreeMap<String, String>> drugDetailList = new ArrayList<>();
            String data = HttpsUtil.getHttps(baseUri);
            int pageCount = getPageCount(data);
            for (int i = nowPage; i <= pageCount; i++) {
                String pageUri = baseUri + "?pageNo=" + i;
                LOGGER.info("第" + i + "页");
                tempPage = i;
                String pageData = HttpsUtil.getHttps(pageUri);
                String[] drug = getDrugs(pageData);
                int length = drug.length;
                String contains = "<div class=\"search-main\"";
                int page = 0;
                for (int j = 0; j < length; j++) {
                    if (drug[j].contains(contains)) {
                        String drugCode = CodeUtil.getCode();
                        String drugName = getDrugName(drug[j]);
                        String drugType = getDrugType(drug[j]);
                        String drugDec = getDrugDec(drug[j]);
                        //存储drug
                        Drug dto = new Drug(drugCode, drugName, drugType, drugDec);
                        drugList.add(dto);

                        TreeMap<String, String> drugDetail = getDrugDetail(drug[j]);
                        drugDetail.put("drugCode", drugCode);
                        drugDetailList.add(drugDetail);
                    }
                }
                if (page % 5 == 0) {

                    batchInsert(drugList,drugDetailList);
                    page = 0;
                    drugList.clear();
                    drugDetailList.clear();
                }
                page++;
            }
        }catch(Exception e){
            LOGGER.info(e.getLocalizedMessage());
            reptileDrugInfo(baseUri,tempPage);
        }
    }

    @Transactional
    public void batchInsert(List<Drug> drugList, List<TreeMap<String, String>> drugDetailList) {
        batchInsertDrug(drugList);
        batchInsertDrugDetail(drugDetailList);
    }

    private void batchInsertDrugDetail(List<TreeMap<String,String>> list) {
        List<TreeMap<String,String>> newList = new ArrayList<TreeMap<String,String>>();
        int size = list.size();
        int num = 100;
        if(size > num ){
            for (int i = 0; i < size ; i++) {
                newList.add(list.get(i));
                if (num == newList.size() || i == size-1) {  //载体list达到要求,进行批量操作
                    //调用批量插入
                    drugMapper.batchInsertDrugDetail(newList);
                    newList.clear();//每次批量操作后,情况载体list,等待下次的数据填入
                }
            }
        }else{
            drugMapper.batchInsertDrugDetail(list);
        }
    }

    private void batchInsertDrug(List<Drug> list) {
        List<Drug> newList = new ArrayList<Drug>();
        int size = list.size();
        int num = 100;
        if(size > num ){
            for (int i = 0; i < size ; i++) {
                newList.add(list.get(i));
                if (num == newList.size() || i == size-1) {  //载体list达到要求,进行批量操作
                    //调用批量插入
                    drugMapper.batchInsertDrug(newList);
                    newList.clear();//每次批量操作后,情况载体list,等待下次的数据填入
                }
            }
        }else{
            drugMapper.batchInsertDrug(list);
        }
    }

    private TreeMap<String,String> getDrugDetail(String drug) {
        String drugDetailStart = "<a href=\"/drug/";
        String drugDetailEnd = " target=\"_blank\"";
        int startIndex = drug.indexOf(drugDetailStart);
        int endIndex = drug.indexOf(drugDetailEnd);

        String drugId = drug.substring(startIndex + drugDetailStart.length(),endIndex-1).trim();

        //获得该药品详情
        String detailUri = "https://www.dayi.org.cn/drug/"+drugId;
        String drugDetailData = HttpsUtil.getHttps(detailUri);

        TreeMap<String,String> baseMap = getDrugBaseMap(drugDetailData);

        TreeMap<String,String> detailMap = getDetailMap(drugDetailData);

        baseMap.putAll(detailMap);
        return baseMap;
    }

    private TreeMap<String, String> getDetailMap(String drugDetail) {
        TreeMap<String,String> retMap = new TreeMap<>();

        String start = "<div class=\"long-container\" data-v-99595782 data-v-a55caf0a>";
        String end = "</article>";
        String split = "<div data-v-99595782>";
        int startIndex = drugDetail.indexOf(start);
        int endIndex = drugDetail.indexOf(end);
        String baseDetail = drugDetail.substring(startIndex,endIndex);
        String[] detail = baseDetail.split(split);
        int length = detail.length;

        for(int i = 0;i < length;i++) {
            if (detail[i].contains("class=\"one-title\" data-v-99595782>")) {
                int keyStartIndex = detail[i].indexOf("<h2 data-v-99595782>") + ("<h2 data-v-99595782>").length();
                int keyEndIndex = detail[i].indexOf("</h2>");
                String key = detail[i].substring(keyStartIndex,keyEndIndex);

                int valueStartIndex = detail[i].lastIndexOf("<div class=\"field-content\" data-v-99595782>")+ ("<div class=\"field-content\" data-v-99595782>").length();
                int valueEndIndex = detail[i].indexOf("</p></div></div>");
                if(valueEndIndex == -1){
                    valueEndIndex = detail[i].lastIndexOf("</div></div>");
                }else{
                    valueEndIndex = valueEndIndex +4;
                }
                String value = detail[i].substring(valueStartIndex,valueEndIndex);
                retMap.put(key,value);
            }
        }
        return retMap;
    }

    private TreeMap<String, String> getDrugBaseMap(String drugDetail) {
        TreeMap<String,String> retMap = new TreeMap<>();

        String start = "<div class=\"short-field-container\" data-v-b6c16c48>";
        String end = "<div class=\"catalog-container\" data-v-4c140b70 data-v-a55caf0a>";
        String split = "<div class=\"shortDiv\" data-v-b6c16c48>";
        int startIndex = drugDetail.indexOf(start);
        int endIndex = drugDetail.indexOf(end);
        String baseDetail = drugDetail.substring(startIndex,endIndex);
        String[] detail = baseDetail.split(split);
        int length = detail.length;
        for(int i = 0;i < length;i++){
            if(detail[i].contains("<p class=\"short-field-title\" data-v-b6c16c48>")){
                int keyStartIndex = ("<p class=\"short-field-title\" data-v-b6c16c48>").length();
                int keyEndIndex = detail[i].indexOf("<div class=\"bigDiv\" data-v-60dea19a data-v-b6c16c48>")-5;
                String key = detail[i].substring(keyStartIndex,keyEndIndex);

                int valueStartIndex = detail[i].indexOf("<span class=\"short-field-content\" data-v-b6c16c48>")+ ("<span class=\"short-field-content\" data-v-b6c16c48>").length();
                int valueEndIndex = detail[i].indexOf("</span></div></div>");
                String value = detail[i].substring(valueStartIndex,valueEndIndex);
                retMap.put(key,value);
            }
        }
        return retMap;
    }

    private String getDrugDec(String drug) {
        String drugDecStart = "<div class=\"text\" style=\"max-height: 82px;\" data-v-12966664>";
        String drugDecEnd = "<div style=\"font-size: 14px;display: flex;cursor: pointer;line-height: 27px;\" data-v-12966664>";
        int drugDecStartIndex = drug.indexOf(drugDecStart) + drugDecStart.length();
        int drugDecEndIndex = drug.indexOf(drugDecEnd) -7;
        String drugDec = drug.substring(drugDecStartIndex,drugDecEndIndex);
        return drugDec;
    }

    private String getDrugType(String drug) {
        String drugTypeStart = "<span style=\"color:#0366F2;\" data-v-12966664>";
        String drugTypeEnd = "</span>";
        int drugTypeStartIndex = drug.indexOf(drugTypeStart) + drugTypeStart.length();
        int drugTypeEndIndex = drug.indexOf(drugTypeEnd);
        String drugType = drug.substring(drugTypeStartIndex,drugTypeEndIndex).replace("\n","").trim();
        return drugType;
    }

    private String getDrugName(String drug) {
        String drugNameStart = "class=\"name\" style=\"color:#0366F2\" data-v-12966664>";
        String drugNameEnd = "</a>";
        int drugNameStartIndex = drug.indexOf(drugNameStart) + drugNameStart.length();
        int drugNameEndIndex = drug.indexOf(drugNameEnd);
        String drugName = drug.substring(drugNameStartIndex,drugNameEndIndex);
        return drugName;
    }

    private String[] getDrugs(String pageData) {
        String start = "<div class=\"list-left\" data-v-026af858>";
        String end = "<div class=\"list-right\" data-v-026af858>";
        int startIndex = pageData.indexOf(start);
        int endIndex = pageData.indexOf(end);
        String drugList = pageData.substring(startIndex,endIndex);

        String split = "<div data-v-303889e8 data-v-026af858>";

        String[] drug = drugList.split(split);
        return drug;
    }

    private int getPageCount(String data) {
        String pageStart = "<div size-change=\"size\" class=\"el-pagination\" data-v-5874d41a>";
        String pageEnd = "<span class=\"el-pagination__jump\">";

        int pageStartIndex = data.indexOf(pageStart);
        int pageEndIndex = data.indexOf(pageEnd);
        String page = data.substring(pageStartIndex,pageEndIndex);

        String pageSplit = "<li class=\"number\">";
        String[] pages = page.split(pageSplit);
        int pageCount = Integer.valueOf(pages[pages.length-1].substring(0,pages[pages.length-1].indexOf("</li>")));
        return pageCount;
    }
}
